home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Explosion
/
Software Explosion (Fore-Matt Home Computing)(1996).iso
/
games
/
workbench
/
lander_2
/
source
/
player.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-01
|
6KB
|
295 lines
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/audio.h>
#include <stdio.h>
#include "sample.h"
#include "sounds.h"
#define YES 1
#define NO 0
extern int debug;
/* #define WHERE fprintf(stderr,"%s %s %d\n",__FILE__,__FUNC__,__LINE__); */
/* #define WHAT(x) fprintf(stderr,"%s %s %d %s\n",__FILE__,__FUNC__,__LINE__,x->name); */
#define WHERE
#define WHAT(x)
#define CLOCKFREQ 3579545
extern Sound *sounds[];
extern int maxsounds;
int audio_up = NO; /* set to yes after initilization is complete, */
/* used by "endaudio" to figure out clean up */
struct Device *AudioDevice;
struct MsgPort *AudioPort;
struct IOAudio *openIOB;
static UBYTE LeftMap[] = {LEFT0, LEFT1};
static UBYTE RightMap[] = {RIGHT0, RIGHT1};
static UBYTE TryLeftMap[] = {LEFT1, LEFT0, RIGHT1, RIGHT0};
static UBYTE TryRightMap[] = {RIGHT1, RIGHT0, LEFT1, LEFT0};
_abort()
{
fputs("abort caused by ^C or audio panic\n",stderr);
cleanup(debug);
exit(10);
}
panic(s)
char *s;
{
fprintf(stderr,"panic: %s\n",s);
_abort();
}
struct IOAudio *IOBallocate()
{
struct IOAudio *IOB;
if ((IOB = (struct IOAudio *)AllocMem(sizeof(struct IOAudio), MEMF_PUBLIC | MEMF_CLEAR)) == (struct IOAudio *) NULL)
panic("IOBallocate failed");
return(IOB);
}
IOBfree(IOBp)
struct IOAudio *IOBp;
{
if (IOBp != NULL)
FreeMem(IOBp, sizeof(struct IOAudio));
}
InitPlayIOB(soundp)
Sound *soundp;
{
struct IOAudio *IOB = soundp->IOBs[PLAY_IOB];
IOB->ioa_Request.io_Command = CMD_WRITE;
IOB->ioa_Request.io_Flags = ADIOF_PERVOL;
IOB->ioa_Volume = soundp->volume;
IOB->ioa_Cycles = soundp->cycles;
IOB->ioa_Data = (UBYTE *)&soundp->samplep->sampledata[0];
IOB->ioa_Length = (ULONG)soundp->samplep->nsamples;
IOB->ioa_Period = (CLOCKFREQ / soundp->samplep->sampsec) + soundp->detune;
}
InitStopIOB(soundp)
Sound *soundp;
{
struct IOAudio *IOB = soundp->IOBs[STOP_IOB];
IOB->ioa_Request.io_Command = ADCMD_FINISH;
IOB->ioa_Request.io_Flags = IOF_QUICK;
}
InitAllocIOB(soundp)
Sound *soundp;
{
struct IOAudio *allocIOB = soundp->IOBs[ALLOC_IOB];
allocIOB->ioa_Request.io_Command = ADCMD_ALLOCATE;
allocIOB->ioa_Request.io_Message.mn_Node.ln_Pri = soundp->precedence;
if (!soundp->flags & EITHER) {
allocIOB->ioa_Data = (soundp->flags & LEFT) ? LeftMap : RightMap;
allocIOB->ioa_Length = 2;
} else {
allocIOB->ioa_Data = (soundp->flags & LEFT) ? TryLeftMap : TryRightMap;
allocIOB->ioa_Length = 4;
}
allocIOB->ioa_Request.io_Flags = (ADIOF_NOWAIT | IOF_QUICK);
}
InitDeallocIOB(soundp)
Sound *soundp;
{
struct IOAudio *IOB = soundp->IOBs[FREE_IOB];
IOB->ioa_Request.io_Command = ADCMD_FREE;
IOB->ioa_Request.io_Flags = IOF_QUICK;
}
initsound(soundindex)
int soundindex;
{
int i;
struct IOAudio *IOB;
Sound *soundp = sounds[soundindex];
if ((soundp->port = CreatePort(soundp->name, 0)) == 0)
{
fprintf(stderr,"can't create audio port \"%s\"\n",soundp->name);
panic("can't create audio port");
}
for (i = 0; i < MAX_SOUND_IOBS; i++)
{
IOB = soundp->IOBs[i] = IOBallocate();
IOB->ioa_Request.io_Message.mn_ReplyPort = soundp->port;
IOB->ioa_Request.io_Device = AudioDevice;
/* We assign our own AllocKeys so we'll have a handle to determine
* which sound structure we received at a reply port. This also
* makes playtime overhead less by not having to throw around
* dynamically-allocated allocation keys. If AllocKey
* is zero when channels are allocated, a key is dynamically assigned
* We use soundindex + 1 instead of soundindex to prevent a zero
* allockey. Also, we reduce playtime overhead by not throwing
* dynamically-assigned keys around.
*/
IOB->ioa_AllocKey = soundindex + 1;
}
InitPlayIOB(soundp);
InitStopIOB(soundp);
InitAllocIOB(soundp);
InitDeallocIOB(soundp);
}
initaudio()
{
int i;
openIOB = IOBallocate();
if (OpenDevice(AUDIONAME, 0, openIOB, 0) != 0)
panic("can't open audio device");
AudioDevice = openIOB->ioa_Request.io_Device;
for (i = 0; i < maxsounds; i++)
initsound(i);
audio_up = YES;
}
endaudio()
{
int i, j;
if (audio_up)
{
for (i = 0; i < maxsounds; i++)
StopSound(sounds[i]);
}
for (i = 0; i < maxsounds; i++)
{
for (j = 0; j < MAX_SOUND_IOBS; j++)
IOBfree(sounds[i]->IOBs[j]);
if (sounds[i]->port)
DeletePort(sounds[i]->port,sizeof(struct MsgPort));
}
CloseDevice(openIOB);
IOBfree(openIOB);
}
PlaySound(soundp)
Sound *soundp;
{
int i;
struct IOAudio *allocIOB = soundp->IOBs[ALLOC_IOB];
struct IOAudio *playIOB = soundp->IOBs[PLAY_IOB];
if (soundp->flags & PLAYING)
return;
BeginIO(allocIOB);
/* the only possible error return is ADIOERR_NOALLOCATION */
if (allocIOB->ioa_Request.io_Error)
return;
for (i = PLAY_IOB; i <= FREE_IOB; i++)
soundp->IOBs[i]->ioa_Request.io_Unit = allocIOB->ioa_Request.io_Unit;
BeginIO(playIOB);
/* possible errors are IOERR_ABORTED and ADIOERR_NOALLOCATION */
if (playIOB->ioa_Request.io_Error)
return;
soundp->flags |= PLAYING;
}
DeallocSound(soundp)
Sound *soundp;
{
struct IOAudio *freeIOB = soundp->IOBs[FREE_IOB];
BeginIO(freeIOB);
/* only possible error return is ADIOERR_NOALLOCATION */
}
StopSound(soundp)
Sound *soundp;
{
struct IOAudio *stopIOB = soundp->IOBs[STOP_IOB];
struct IOAudio *freeIOB= soundp->IOBs[FREE_IOB];
WHAT(soundp);
if (soundp->flags & PLAYING)
{
soundp->flags &= ~PLAYING;
BeginIO(stopIOB);
/* only error return is ADIOERR_NOALLOCATION */
WaitIO(soundp->IOBs[PLAY_IOB]);
/* error returns can be IOERR_ABORTED and ADIOERR_NOALLOCATION */
}
DeallocSound(soundp);
}
WaitSound(soundp)
Sound *soundp;
{
WHAT(soundp);
if (soundp->flags & PLAYING)
{
WaitIO(soundp->IOBs[PLAY_IOB]);
soundp->flags &= ~PLAYING;
}
DeallocSound(soundp);
}
dumpsound(soundp)
Sound *soundp;
{
printf("dump of sound %s\n",soundp->name);
printf("cycles %d, volume %d, flags %d, precedence %d, detune %d\n",
soundp->cycles, soundp->volume, soundp->flags, soundp->precedence,
soundp->detune);
dumpsample(soundp->samplep);
}
dumpsample(samptr)
Sample *samptr;
{
int i, linect;
printf("nsamples %d, sampsec %d\n",samptr->nsamples, samptr->sampsec);
/* for (i = 0; i < samptr->nsamples; i++)
{
printf("%4d ",samptr->sampledata[i]);
if (++linect > 14)
{
putchar('\n');
linect = 0;
}
} */
}